﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using StreetlightGames.XnaEngine;

namespace StreetlightGames.SpaceShooter
{
    public class Explosion
    {
        /// <summary>Gets or sets the IsAlive value</summary>
        public bool IsAlive
        {
            get { return _particles.Count > 0; }
            set
            {
                if (!value)
                {
                    _particles.Clear();
                }
            }
        }
        
        private const int PARTICLE_COUNT = 100;
        private Vector3 _position;
        private List<ExplosionParticle> _particles = new List<ExplosionParticle>();
        private VertexDeclaration _vertexDeclaration;
        private BasicEffect _basicEffect;
        private double _totalElapsedTime;

        public Explosion()
        {
        }

        public void Initialize(GraphicsDevice graphicsDevice)
        {
            _vertexDeclaration = new VertexDeclaration(graphicsDevice, VertexPositionColor.VertexElements);
            _basicEffect = new BasicEffect(graphicsDevice, null);
            _basicEffect.VertexColorEnabled = true;
            _basicEffect.World = Matrix.Identity;
        }

        public void Start(Vector3 position, Vector3 velocity)
        {
            _totalElapsedTime = 0;
            _position = position;
            _particles.Clear();
            for (int i = 0; i < PARTICLE_COUNT; i++)
            {
                _particles.Add(new ExplosionParticle(
                    new VertexPositionColor(
                        _position,
                        Color.White),
                    velocity + new Vector3(
                        RandomHelper.NextFloat(-100, 100),
                        RandomHelper.NextFloat(-100, 100),
                        RandomHelper.NextFloat(-100, 100)),
                    RandomHelper.NextDouble(0, 1)));
            }
        }

        public void Update(GameTime gameTime)
        {
            _totalElapsedTime += gameTime.ElapsedGameTime.TotalSeconds;
            _particles.RemoveAll(
                delegate(ExplosionParticle particle)
                {
                    return particle.BurnTime < _totalElapsedTime;
                });
            for (int i = 0; i < _particles.Count; i++)
            {
                _particles[i].Update(gameTime);
            }
        }

        public void Draw(GraphicsDeviceManager graphicsDeviceManager, Camera camera)
        {
            _basicEffect.View = camera.ViewMatrix;
            _basicEffect.Projection = camera.ProjectionMatrix;

            graphicsDeviceManager.GraphicsDevice.VertexDeclaration = _vertexDeclaration;

            _basicEffect.Begin();

            VertexPositionColor[] vertexes = new VertexPositionColor[_particles.Count];
            for (int i = 0; i < vertexes.Length; i++)
            {
                vertexes[i] = _particles[i].Vertex;
            }

            foreach (EffectPass pass in _basicEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                graphicsDeviceManager.GraphicsDevice.RenderState.PointSize = 1;
                graphicsDeviceManager.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
                    PrimitiveType.PointList,
                    vertexes,
                    0,
                    vertexes.Length);
                pass.End();
            }

            _basicEffect.End();
        }
    }
}
